home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / 3d_lib.zip / NORM.C < prev    next >
C/C++ Source or Header  |  1993-05-09  |  4KB  |  108 lines

  1. /* Calculate normal to face
  2.  
  3.    Copyright (c) 1988 by Gus O'Donnell
  4.  
  5.    Revision history:
  6.  
  7.    Version 1.00         February 29, 1988       As released.
  8.  
  9.    Version 1.01         March 20, 1988          Created libraries for all
  10.                                                 memory models
  11.  
  12. */
  13. #include "3d.h"
  14. #include <float.h>
  15. #include <stdio.h>
  16. #include <math.h>
  17.  
  18. int     normal (FACE *this_face, VECTOR norm)
  19.  
  20. /* Calculate the normal to the face.  The normal is calculated as the
  21. cross product of two sides of the face.  The face must have at least
  22. three corners.  The first three corners must not be colinear.  Since
  23. each corner added to the face using add_corner is checked for colinearity,
  24. this check is not performed here.  The function also assumes that the
  25. face is a convex polygon; if the first two sides of the face are at an
  26. angle greater than 180 degrees (i.e., the face is a concave polygon), the
  27. normal will have the wrong sign.  Finally, the function assumes that the
  28. corners are listed in clockwise order, viewing the face from the outside
  29. of the solid.
  30.  
  31. Given two vectors
  32.  
  33.                  q = [Ai + Bj + Ck],
  34.                  r = [Di + Ej + Fk]
  35.  
  36. where i, j, and k are orthogonal unit vectors, the cross product p = q X r
  37. is given by:
  38.  
  39.                  p = [(B*F) - (C*E)]i
  40.                    + [(C*D) - (A*F)]j
  41.                    + [(A*E) - (B*D)]k
  42.  
  43. If the first three corners of the face are a, b, and c, the components of
  44. the vectors forming the first two sides q and r are
  45.  
  46.                  A = a [0] - b [0]
  47.                  B = a [1] - b [1]
  48.                  C = a [2] - b [2]
  49.                  D = c [0] - b [1]
  50.                  E = c [1] - b [2]
  51.                  F = c [2] - b [2]
  52.  
  53. Note that the components are calculated such that corner b corresponds
  54. to the tail of the two vectors.  This yields a normal vector p = q X r
  55. with a direction away from the interior of the solid.  Substituting
  56. the expressions for A through F into the expression for the cross product
  57. gives:
  58.  
  59.                  p = [(a [1] - b [1])*(c [2] - b [2])
  60.                    -  (a [2] - b [2])*(c [1] - b [1])]i
  61.                    + [(a [2] - b [2])*(c [0] - b [0])
  62.                    -  (a [0] - b [0])*(c [2] - b [2])]j
  63.                    + [(a [0] - b [0])*(c [1] - b [1])
  64.                    -  (a [1] - b [1])*(c [0] - b [0])]k
  65.  
  66. This is the result returned in norm.  The function returns an integer
  67. status corresponding to:
  68.  
  69.                      0 - Operation successful.
  70.                      1 - Face has less than three corners.
  71.  
  72. */
  73. {
  74.     VECTOR p [3];       /* Temporary storage for the first three corners. */
  75.  
  76.     CORNER *chandle;
  77.     int index,count;
  78.  
  79.     chandle = this_face -> first -> next;
  80.     for (count = 2; count >= 0; count--)    /* Copy the first three corners
  81.                                                of the face to temporary
  82.                                                storage. */
  83.     {
  84.         if (chandle -> next == NULL) return (1); /* Face has less than three
  85.                                                     corners. */
  86.         for (index = 0; index < DIM; index++)
  87.             p [count] [index] = chandle -> this -> coord [index];
  88.  
  89.         chandle = chandle -> next;
  90.     }
  91.  
  92.     /* In the following expression,
  93.  
  94.                         p[0] = a
  95.                         p[1] = b
  96.                         p[2] = c
  97.  
  98.     */
  99.     norm [0] = ((p[2][1] - p[1][1]) * (p[0][2] - p[1][2]))
  100.              - ((p[2][2] - p[1][2]) * (p[0][1] - p[1][1]));
  101.     norm [1] = ((p[2][2] - p[1][2]) * (p[0][0] - p[1][0]))
  102.              - ((p[2][0] - p[1][0]) * (p[0][2] - p[1][2]));
  103.     norm [2] = ((p[2][0] - p[1][0]) * (p[0][1] - p[1][1]))
  104.              - ((p[2][1] - p[1][1]) * (p[0][0] - p[1][0]));
  105.  
  106.     return (0);
  107. }
  108.